﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIObjects.TreeViewInterfaces;
#if SILVERLIGHT
using AbstraX.ClientInterfaces;
#else
using AbstraX.ServerInterfaces;
#endif
using System.Collections.ObjectModel;
using AbstraX.Contracts;
using MvvmTreeView;
using System.Text.RegularExpressions;
using System.ServiceModel.DomainServices.Client;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls;

namespace AbstraX.ViewModels.ModelTree
{
    public class ModelTreeNodeFolder : ModelTreeNodeBase
    {
        private IQueryable<IBase> baseObjects;
        private string folderPath;
        private string folderKey;
        private string folderKeyPair;
        public override event ImageAvailableHandler ImageAvailable;

        public ModelTreeNodeFolder(IProviderClientService providerService, ITreeView treeView, string folderKeyPair, IQueryable<IBase> baseObjects) : base(providerService, treeView)
        {
            this.baseObjects = baseObjects;
            this.Tag = folderPath;
            this.folderKeyPair = folderKeyPair;

            SetFolderAndKey(folderKeyPair);
        }

        private void SetFolderAndKey(string folderKeyPair)
        {
            var regex = new Regex(@"(?<folder>.*?)\;(?<key>.*)");
            var match = regex.Match(folderKeyPair);

            folderPath = match.Groups["folder"].Value;
            folderKey = match.Groups["key"].Value;
        }

        public string FolderKeyPair
        {
            get 
            { 
                return folderKeyPair; 
            }
        }

        public IQueryable<IBase> BaseObjects
        {
            get 
            {
                return baseObjects; 
            }
        }

        public override IBase BaseObject
        {
            get
            {
                return null;
            }
        }

        public override void OnSelect()
        {
            this.TreeView.FireNodeSelected(this);
        }

        public override string Text
        {
            get
            {
                return folderPath;
            }

            set
            {
                throw new NotImplementedException();
            }
        }

        public override void StartLoadImage()
        {
            var key = folderKey;
            var imageList = treeView.ImageList;

            if (imageList.Images.ContainsKey(key))
            {
                if (imageList.ImageLoadHandlers.ContainsKey(key))
                {
                    var eventHandlers = imageList.ImageLoadHandlers[key];

                    foreach (ImageAvailableHandler handler in ImageAvailable.GetInvocationList())
                    {
                        eventHandlers.Add(handler);
                    }
                }

                ImageAvailable(this);
            }
            else
            {
                if (imageList.ImageLoadHandlers.ContainsKey(key))
                {
                    var eventHandlers = imageList.ImageLoadHandlers[key];

                    foreach (ImageAvailableHandler handler in ImageAvailable.GetInvocationList())
                    {
                        eventHandlers.Add(handler);
                    }
                }
                else
                {
                    var itemType = baseObjects.First().ToString(); 
                    var operation = providerService.LoadImageForFolder(itemType, key);

                    operation.OnImageCompleted += new EventHandler(LoadImage_Completed);
                    imageList.ImageLoadHandlers.Add(key, new List<ImageAvailableHandler>());
                }
            }
        }

        protected void LoadImage_Completed(object sender, EventArgs e)
        {
            var key = folderKey;
            var invokeOperation = (ImageInvokeOperation)sender;
            var imageData = (byte[])invokeOperation.ImageData;
            var imageList = treeView.ImageList;
            var eventHandlers = imageList.ImageLoadHandlers[key];

            imageList.Images.Add(key, imageData, Colors.Transparent);

            ImageAvailable(this);

            foreach (ImageAvailableHandler handler in eventHandlers)
            {
                handler(this);
            }
        }

        public override object Image
        {
            get
            {
                BitmapImage image = null;
                var key = folderKey;

                if (treeView.ImageList.Images.ContainsKey(key))
                {
                    image = treeView.ImageList.Images[key];
                }

                return image;
            }
        }

        public override void Expand()
        {
            if (!this.IsChildrenLoaded)
            {
                LoadChildren();
            }

            ((TreeViewItem)this.TreeViewItem).IsExpanded = true;
            this.isExpanded = true;
        }

        protected override void ChildrenLoaded(IBase parent)
        {
        }

        public override void LoadChildren()
        {
            RemoveSpinster();
            RemoveEditNode();

            isChildrenLoaded = true;

            var elements = baseObjects.Where(b => b is IElement).Cast<IElement>();
            var nodeIds = this.Nodes.Where(n => !(n is ModelTreeNodeFolder)).Select(n => (IBase)n.Tag).Select(b => b.ID);

            elements.Select(r => new ModelTreeNodeElement(providerService, treeView, r)).Where(d => !nodeIds.Any(id => id == ((IBase)(d.Tag)).ID))
            .OrderBy(e => e.ChildOrdinal)
            .ThenBy(e => e.Text)
            .ToList()
            .ForEach(d => this.Nodes.Add(d));

            isChildrenLoaded = true;
        }

        public override List<string> AddNewShortCuts
        {
            get { return new List<string>(); }
        }

        public override void AddNew(string shortCut)
        {
            throw new NotImplementedException();
        }

        public override void DragStarting(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e)
        {
        }

        public override void DragCompleted(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e)
        {
        }

        public override void ItemDropped(object sender, UIObjects.DragDropInterfaces.ItemDragEventArgs e, int insertionIndex)
        {
        }

        public override void GiveFeedback(object sender, UIObjects.DragDropInterfaces.GiveFeedbackEventArgs e)
        {
        }

        public override void DragEnter(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override void DragLeave(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override void DragOver(object sender, UIObjects.DragDropInterfaces.DragEventArgs e)
        {
        }

        public override float ChildOrdinal
        {
            get
            {
                return 0;
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public override bool? HasChildren
        {
            get
            {
                return baseObjects.Count() > 0;
            }
        }
    }
}
